﻿// -----------------------------------------------------------------------
// <copyright file="RadioLogic.cs" company="Abyssalsoft">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace Metal.Player.Radio
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Windows.Forms;
    using System.Xml;
    
    using Metal.Config;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class RadioLogic
    {
        #region Members

        /// <summary> Stores reference to our instance </summary>
        private static RadioLogic instance = null;

        #endregion

        #region Constructor

        /// <summary> Gets the current instance of this class (Singleton - Thread safety) </summary>
        public static RadioLogic Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new RadioLogic();
                }

                return instance;
            }
        }

        #endregion

        #region Methods called by reflection

        /// <summary>
        /// Create new playlist
        /// </summary>
        public void NewCategory()
        {
            try
            {
                Metal.CommonForms.SaveForm saveForm = new CommonForms.SaveForm("New list", "Enter the name of the list");
                saveForm.ShowDialog();
                RadioController.CurrentFileName = saveForm.FileName;

                if (saveForm.FileName != string.Empty)
                {
                    // Clear ListView
                    RadioController.ListDataSet.Tables[0].Rows.Clear();

                    XmlWriterSettings xmlSettings = new XmlWriterSettings();
                    xmlSettings.Indent = true;
                    xmlSettings.NewLineOnAttributes = true;

                    XmlWriter xmlPlaylist;
                    xmlPlaylist = XmlWriter.Create(Metal.Config.Paths.RadioListsFolder + RadioController.CurrentFileName + ".xml", xmlSettings);
                    RadioController.ListDataSet.WriteXml(xmlPlaylist);
                    xmlPlaylist.Close();

                    // Refresh list of playlists
                    this.RefreshListOfCategories();

                    // Select our new list
                    RadioController.SelectRow(2, RadioController.CurrentFileName);

                    // Inform user that our list is saved
                    Metal.User.UserMessage.ShowInfoMessage("Category created!", "Now you can add radio channels into your list.");
                }
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// Show input dialog and add to list
        /// </summary>
        public void AddRadio()
        {
            try
            {
                Metal.CommonForms.AddUrlForm addUrl = new CommonForms.AddUrlForm();
                addUrl.ShowDialog();

                if (addUrl.RadioURL != null & addUrl.RadioName != null)
                {
                    this.AddFileToList(addUrl.RadioURL, addUrl.RadioName);
                    RadioController.SaveCurrentList();
                }
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// Show open dialog and add to list
        /// </summary>
        public void AddRadioFile()
        {
            try
            {
                OpenFileDialog fileBrowser = new OpenFileDialog();
                ////fileBrowser.Filter = "Playlist Files|*.pls;*.xls;*.ppt";
                fileBrowser.Filter = "Playlist Files|*.pls";
                fileBrowser.ShowDialog();
                if (fileBrowser.FileName != string.Empty)
                {
                    Metal.CommonForms.TextEditorForm editor = new CommonForms.TextEditorForm();
                    editor.InfoText = "Enter the radio name";
                    editor.ShowDialog();

                    // Get the url from file
                    string url = string.Empty;
                    bool found = false;

                    foreach (string line in File.ReadAllLines(fileBrowser.FileName))
                    {
                        if (!found)
                        {
                            if (line.Contains("http://"))
                            {
                                int startIndex = line.IndexOf("http");
                                url = line.Substring(startIndex, line.Length - startIndex);
                                found = true;
                            }
                        }
                    }

                    this.AddFileToList(url, editor.EditorText);
                }

                RadioController.SaveCurrentList();
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// Clear current category
        /// </summary>
        public void ClearCategory()
        {
            try
            {
                RadioController.ListDataSet.Tables[0].Rows.Clear();

                RadioController.SaveCurrentList();
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// Show playlist settings
        /// </summary>
        public void RadioSettings()
        {
            try
            {
                SettingsForm settings = new Config.SettingsForm(SettingsForm.ShowTab.Playlist);
                settings.ShowDialog();
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// Show file information form (ID3 Tags and MPEG info)
        /// </summary>
        public void OpenFileInfo()
        {
            try
            {
                Metal.CommonForms.FileInfoForm fileInfoForm = new CommonForms.FileInfoForm();
                fileInfoForm.ShowDialog();
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// Show / hide a list of playlists
        /// </summary>
        public void ShowCategories()
        {
            if (RadioController.CurrentView.CategoriesVisible == true)
            {
                RadioController.CurrentView.CategoriesVisible = false;
                Settings.Instance.SetValue("LastSettings.ShowListOfCategories", false);
            }
            else
            {
                RadioController.CurrentView.CategoriesVisible = true;
                Settings.Instance.SetValue("LastSettings.ShowListOfCategories", true);
            }
        }

        /// <summary>
        /// Rename selected playlist
        /// </summary>
        public void RenameCategory()
        {
            try
            {
                Metal.CommonForms.RenameForm renameForm = new CommonForms.RenameForm(RadioController.CurrentView.CategoriesSelectedRow.Cells[1].Value.ToString());
                renameForm.ShowDialog();

                // Refresh
                this.RefreshListOfCategories();
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// Rename selected playlist
        /// </summary>
        public void RenameRadio()
        {
            try
            {
                if (RadioController.CurrentView.ListSelectedRow != null)
                {
                    Metal.CommonForms.TextEditorForm textEditor = new CommonForms.TextEditorForm();
                    textEditor.Text = "Rename";
                    textEditor.EditorText = RadioController.CurrentView.ListSelectedRow.Cells[2].Value.ToString();
                    textEditor.InfoText = "Rename radio";
                    textEditor.ShowDialog();

                    string newName = textEditor.EditorText;
                    if (newName != string.Empty && textEditor.Canceled == false)
                    {
                        RadioController.CurrentView.ListSelectedRow.Cells[2].Value = newName;
                    }

                    // Save
                    RadioController.SaveCurrentList();
                }
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// Change radio link
        /// </summary>
        public void EditLink()
        {
            try
            {
                if (RadioController.CurrentView.ListSelectedRow != null)
                {
                    Metal.CommonForms.TextEditorForm textEditor = new CommonForms.TextEditorForm();
                    textEditor.Text = "Edit link";
                    textEditor.EditorText = RadioController.CurrentView.ListSelectedRow.Cells[1].Value.ToString();
                    textEditor.InfoText = "Edit radio link";
                    textEditor.ShowDialog();

                    string newName = textEditor.EditorText;
                    if (newName != string.Empty && textEditor.Canceled == false)
                    {
                        RadioController.CurrentView.ListSelectedRow.Cells[1].Value = newName;
                    }

                    // Save
                    RadioController.SaveCurrentList();
                }
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// Delete selected playlist
        /// </summary>
        public void DeleteCategory()
        {
            try
            {
                if (Metal.User.UserMessage.ShowInfoMessage(Metal.Resources.MessageProvider.GetMessage("RES00058"), Metal.Resources.MessageProvider.GetMessage("RES00059"), true) == true)
                {
                    System.IO.File.Delete(RadioController.CurrentView.CategoriesSelectedRow.Cells[1].Value.ToString());

                    // Refresh
                    this.RefreshListOfCategories();
                }
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// Delete selected radio
        /// </summary>
        public void DeleteRadio()
        {
            try
            {
                if (RadioController.CurrentView.ListSelectedRow != null)
                {
                    if (Metal.User.UserMessage.ShowInfoMessage(Metal.Resources.MessageProvider.GetMessage("RES00080"), Metal.Resources.MessageProvider.GetMessage("RES00081"), true) == true)
                    {
                        int selectedIndex = Convert.ToInt32(RadioController.CurrentView.ListSelectedRow.Cells[0].RowIndex);
                        RadioController.ListDataSet.Tables[0].Rows[selectedIndex].Delete();
                        RadioController.SaveCurrentList();
                    }
                }
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// Play selected file
        /// </summary>
        public void PlaySelected()
        {
            try
            {
                if (RadioController.CurrentView.ListSelectedRow != null)
                {
                    // Set the radio name, in case the streaming does not return ID3 tags
                    Core.Player.MediaInfo.RadioName = RadioController.CurrentView.ListSelectedRow.Cells[2].Value.ToString();
                    Core.Player.Playback.Instance.Open(RadioController.CurrentView.ListSelectedRow.Cells[1].Value.ToString());
                    Core.Player.Playback.Instance.Play();
                }
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        #endregion

        /// <summary>
        /// Add radio to current category
        /// </summary>
        /// <param name="radioURL">The radio URL</param>
        /// <param name="radioName">The radio name</param>
        public void AddFileToList(string radioURL, string radioName)
        {
            try
            {
                RadioController.ListDataSet.Tables[0].Rows.Add(RadioController.ListDataSet.Tables[0].Rows.Count + 1, radioURL, radioName);
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }

        /// <summary>
        /// Refresh the list of categories
        /// </summary>
        private void RefreshListOfCategories()
        {
            try
            {
                // Reload list of playlists
                RadioController.CategoriesDataSet.Clear();
                string[] files = System.IO.Directory.GetFiles(Metal.Config.Paths.RadioListsFolder);

                int nrOfLists = 0;

                foreach (string file in files)
                {
                    RadioController.CategoriesDataSet.Tables[0].Rows.Add(nrOfLists, file, System.IO.Path.GetFileNameWithoutExtension(file));
                    nrOfLists++;
                }

                // Update
                RadioController.CurrentView.CategoriesDataSet = RadioController.CategoriesDataSet;

                RadioController.SelectRow(2, RadioController.CurrentFileName);
            }
            catch (Exception ex)
            {
                Metal.User.UserMessage.ShowError(ex);
            }
        }
    }
}
